﻿
//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////

#include "CmdPickModuleEntry.h"
#include "IControl.h"
#include "StringUtil.h"
#include "IRibbonGroup.h"
#include "IGroupHandler.h"
#include "IActionManager.h"
#include "ILabelDefinition.h"
#include "IComboBoxHandler.h"
#include "GcmpCommandState.h"
#include "ILineEditHandler.h"
#include "IComboBoxEventArgs.h"
#include "ILineEditEventArgs.h"
#include "UiDocumentViewUtils.h"
#include "ILineEditDefinition.h"
#include "IComboBoxDefinition.h"
#include "IRibbonContextualPage.h"
#include "ICommandButtonDefinition.h"
#include "ICheckBoxGroupDefinition.h"
#include "IControlDefinitionLibrary.h"

#include "UiBuilder.h"
#include "PickFilterDlg.h"
#include "CommandRegister.h"
#include "SampleUIUtils.h"
#include "PickSnapCommandIds.h"
#include "EnableCompileWarning_The_LAST_IncludeInCpp.h" 


/// 本文件是界面实现的辅助类，不包含GDMP API的演示内容

using namespace Sample;
using namespace gcmp;

#define ID_CMD_GBMP_MODIFY                        L"gbmpModifyCmd"

#pragma region 各种Ribbon控件的状态控制

// 拾取API下拉菜单
class PickComboBoxHandler : public IComboBoxHandler
{

public:
    PickComboBoxHandler(std::wstring id)
    {
        m_id = id;
    }

    virtual bool IsVisible() const override { return true; }

    virtual bool IsEnabled()const override { return true; }

    static void UpdateCheckBoxGroup(ICheckBoxGroupDefinition* pCheckBoxGroupDefinition, PickMethod pickMethod)
    {
        if (pickMethod == PickMethod::IPicker)
        {
            pCheckBoxGroupDefinition->SetEnabled(ID_CHECKBOX_SELECT_PICK, true);
            pCheckBoxGroupDefinition->SetEnabled(ID_CHECKBOX_OFFSET_RAY, true);
            pCheckBoxGroupDefinition->SetEnabled(ID_CHECKBOX_IS_MULTIPLE, false);
            pCheckBoxGroupDefinition->SetEnabled(ID_CHECKBOX_VIEWPORT_CUTTED, true);
            pCheckBoxGroupDefinition->SetEnabled(ID_CHECKBOX_PICK_NULL, false);
        }
        else if (pickMethod == PickMethod::PickNodeReferenceAction)
        {
            pCheckBoxGroupDefinition->SetEnabled(ID_CHECKBOX_SELECT_PICK, true);
            pCheckBoxGroupDefinition->SetEnabled(ID_CHECKBOX_OFFSET_RAY, false);
            pCheckBoxGroupDefinition->SetEnabled(ID_CHECKBOX_IS_MULTIPLE, false);
            pCheckBoxGroupDefinition->SetEnabled(ID_CHECKBOX_VIEWPORT_CUTTED, false);
            pCheckBoxGroupDefinition->SetEnabled(ID_CHECKBOX_PICK_NULL, true);
        }
        else
        {
            pCheckBoxGroupDefinition->SetEnabled(ID_CHECKBOX_SELECT_PICK, true);
            pCheckBoxGroupDefinition->SetEnabled(ID_CHECKBOX_OFFSET_RAY, false);
            pCheckBoxGroupDefinition->SetEnabled(ID_CHECKBOX_IS_MULTIPLE, true);
            pCheckBoxGroupDefinition->SetEnabled(ID_CHECKBOX_VIEWPORT_CUTTED, false);
            pCheckBoxGroupDefinition->SetEnabled(ID_CHECKBOX_PICK_NULL, false);
        }
    }

    virtual void On(IComboBoxEventArgs* pArgs) override
    {
        // 根据拾取API接口设置checkbox的可见性
        PickMethod pickMethod = pArgs->GetCurrentData().cast<PickMethod>();
        if (IRibbonGroup* pRibbonGroup = CmdPickModuleEntry::GetRibbonGroup())
        {
            IControl* pControl = pRibbonGroup->GetControl(ID_CHECKBOX_GROUP_PICK);
            DBG_WARN_AND_RETURN_VOID_UNLESS(pControl, L"pControl为空",L"GDMP",L"2023-12-30");
            ICheckBoxGroupDefinition* pCheckBoxGroupDefinition = dynamic_cast<ICheckBoxGroupDefinition*>(pControl->GetControlDefinition());
            DBG_WARN_AND_RETURN_VOID_UNLESS(pCheckBoxGroupDefinition, L"pCheckBoxGroupDefinition为空",L"GDMP",L"2023-12-30");

            PickMethod pickMethod = CmdPickModuleEntry::GetPickMethod();
            PickFilterDlg* pPickFilterDlg = PickFilterDlg::Get();
            DBG_WARN_AND_RETURN_VOID_UNLESS(pPickFilterDlg, L"pPickFilterDlg为空",L"GDMP",L"2023-12-30");
            pPickFilterDlg->SetPickMethod(pickMethod);

            UpdateCheckBoxGroup(pCheckBoxGroupDefinition, pickMethod);

            for (auto itor : pRibbonGroup->GetAllControls())
            {
                DBG_WARN_AND_RETURN_VOID_UNLESS(itor, L"itor为空",L"GDMP",L"2023-12-30");
                itor->UpdateStatus();
            }
        }

        ICommandManager* pCommandManager = ICommandManager::Get();
        DBG_WARN_AND_RETURN_VOID_UNLESS(pCommandManager, L"pCommandManager为空",L"GDMP",L"2023-12-30");
        IActionManager::Reset();
        pCommandManager->SendCommand(ID_CMD_GBMP_MODIFY);
    }
private:
    std::wstring m_id;
};

// 拾取像素容差文本框
class PickLineEditHandler : public ILineEditHandler
{

public:
    virtual bool IsVisible() const override
    {
        return true;
    }

    virtual bool IsEnabled() const override 
    {
        return CmdPickModuleEntry::GetPickMethod() == PickMethod::IPicker || CmdPickModuleEntry::GetPickMethod() == PickMethod::PickNodeReferenceAction;
    }

    virtual void On(ILineEditEventArgs* pArgs) override
    {
        bool ok;
        int num = StringUtil::ToNumber<int>(pArgs->GetText(), &ok);
        if (!ok || num <= 0)
        {
            if (IRibbonGroup* pRibbonGroup = CmdPickModuleEntry::GetRibbonGroup())
            {
                IControl* pControl = pRibbonGroup->GetControl(ID_LINE_PICK_TOLERANCE);
                DBG_WARN_AND_RETURN_VOID_UNLESS(pControl, L"pControl为空",L"GDMP",L"2023-12-30");
                ILineEditDefinition* pCheckBoxGroupDefinition = dynamic_cast<ILineEditDefinition*>(pControl->GetControlDefinition());
                DBG_WARN_AND_RETURN_VOID_UNLESS(pCheckBoxGroupDefinition, L"pCheckBoxGroupDefinition为空",L"GDMP",L"2023-12-30");
                pCheckBoxGroupDefinition->SetText(L"10");
            }
        }
    }
};

// 整个拾取模块Ribbon可见性控制
class PickGroupHandler : public IGroupHandler
{

public:
    virtual bool IsVisible() const override
    {
        return GcmpCommandState::IsInDocumentEnvironment();
    }
};
#pragma endregion 各种Ribbon控件的状态控制

#pragma  region CmdPickHelp
REGISTER_COMMAND(CmdPickHelp)

CmdPickHelp::CmdPickHelp() : CommandBase(ID_CMD_PICK_HELP) {}
CmdPickHelp::~CmdPickHelp() {}

gcmp::OwnerPtr<gcmp::IAction> CmdPickHelp::ExecuteCommand(const gcmp::CommandParameters& cmdParams)
{
    ShellExecute(NULL, L"open", L"https://developer.glodon.com/docs/gdmp/24.0.0305.0/cppdev/szc55z88", NULL, NULL, SW_SHOWNORMAL);
    return nullptr;
}

bool CmdPickHelp::IsEnabled() const
{
    return GcmpCommandState::IsInDocumentEnvironment();
}

bool CmdPickHelp::IsVisible() const
{
    return GcmpCommandState::IsInDocumentEnvironment();
}
#pragma endregion

#pragma region CmdPickModuleEntry

REGISTER_COMMAND(CmdPickModuleEntry)

CmdPickModuleEntry::CmdPickModuleEntry() : CommandBase(ID_CMD_PICK_ENTRY){}
CmdPickModuleEntry::~CmdPickModuleEntry(){}

bool CmdPickModuleEntry::IsEnabled() const
{
    return GcmpCommandState::IsInDocumentEnvironment();
}

bool CmdPickModuleEntry::IsVisible() const
{
    return GcmpCommandState::IsInDocumentEnvironment();
}

const bool CmdPickModuleEntry::DoSelectPicked()
{
    return GetCheckboxValue(ID_CHECKBOX_GROUP_PICK, ID_CHECKBOX_SELECT_PICK);
}

const bool CmdPickModuleEntry::DoOffsetRay()
{
    return GetCheckboxValue(ID_CHECKBOX_GROUP_PICK, ID_CHECKBOX_OFFSET_RAY);
}

const bool Sample::CmdPickModuleEntry::DoSelectMultiple()
{
    return GetCheckboxValue(ID_CHECKBOX_GROUP_PICK, ID_CHECKBOX_IS_MULTIPLE);
}

const bool Sample::CmdPickModuleEntry::DoSelectCutViewPort()
{
    return GetCheckboxValue(ID_CHECKBOX_GROUP_PICK, ID_CHECKBOX_VIEWPORT_CUTTED);
}

const bool Sample::CmdPickModuleEntry::DoClearSelectionBeforeCmd()
{
    return GetCheckboxValue(ID_CHECKBOX_GROUP_PICK, ID_CHECKBOX_CLEAR_SELECTION);
}

const bool Sample::CmdPickModuleEntry::DoPickNullReturnPos()
{
    return GetCheckboxValue(ID_CHECKBOX_GROUP_PICK, ID_CHECKBOX_PICK_NULL);
}

const bool Sample::CmdPickModuleEntry::DoUseCustomeAction()
{
    return GetCheckboxValue(ID_CHECKBOX_GROUP_PICK, ID_CHECKBOX_CUSTOM_ACTION);
}

const int Sample::CmdPickModuleEntry::GetTolerance()
{
    if (IRibbonGroup* pRibbonGroup = GetRibbonGroup())
    {
        IControl* pControl = pRibbonGroup->GetControl(ID_LINE_PICK_TOLERANCE);
        DBG_WARN_AND_RETURN_UNLESS(pControl, 10, L"pControl为空",L"GDMP",L"2023-12-30");
        ILineEditDefinition* pCheckBoxGroupDefinition = dynamic_cast<ILineEditDefinition*>(pControl->GetControlDefinition());
        DBG_WARN_AND_RETURN_UNLESS(pCheckBoxGroupDefinition, 10, L"pCheckBoxGroupDefinition为空",L"GDMP",L"2023-12-30");
        bool ok;
        int tolearance = StringUtil::ToNumber<int>(pCheckBoxGroupDefinition->GetText(), &ok);
        if (ok)
        {
            return tolearance;
        }
    }
    return 10;
}

const PickMethod Sample::CmdPickModuleEntry::GetPickMethod()
{
    IRibbonGroup* pRibbonGroup = GetRibbonGroup();

    if (!pRibbonGroup) return PickMethod::Unknow;
    IControl* pControl = pRibbonGroup->GetControl(ID_COMBOBOX_PICK_METHOD);
    DBG_WARN_AND_RETURN_UNLESS(pControl, PickMethod::Unknow, L"pControl为空",L"GDMP",L"2023-12-30");
    IComboBoxDefinition* pComboBoxPickMethodDefinition = dynamic_cast<IComboBoxDefinition*>(pControl->GetControlDefinition());
    DBG_WARN_AND_RETURN_UNLESS(pComboBoxPickMethodDefinition, PickMethod::Unknow, L"pComboBoxPickMethodDefinition为空",L"GDMP",L"2023-12-30");
    Any userData = pComboBoxPickMethodDefinition->GetCurrentData();
    return userData.cast<PickMethod>();
}

IRibbonGroup* Sample::CmdPickModuleEntry::GetRibbonGroup()
{
    ModuleUIUtils* pModuleUIUtils = ModuleUIUtils::Get();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pModuleUIUtils, L"pModuleUIUtils为空",L"GDMP",L"2023-12-30");
    return SampleUIUtils::FindGroup(ID_PAGE_MODULE, ID_GROUP_MODULE_PICK_CONTEXT);
}

const bool Sample::CmdPickModuleEntry::GetCheckboxValue(std::wstring checkboxGroupId, std::wstring checkboxId)
{
    if (IRibbonGroup* pRibbonGroup = GetRibbonGroup())
    {
        IControl* pControl = pRibbonGroup->GetControl(checkboxGroupId);
        DBG_WARN_AND_RETURN_FALSE_UNLESS(pControl, L"pControl为空",L"GDMP",L"2023-12-30");
        ICheckBoxGroupDefinition* pCheckBoxGroupDefinition = dynamic_cast<ICheckBoxGroupDefinition*>(pControl->GetControlDefinition());
        DBG_WARN_AND_RETURN_FALSE_UNLESS(pCheckBoxGroupDefinition, L"pCheckBoxGroupDefinition为空",L"GDMP",L"2023-12-30");
        bool ok; 
        return pCheckBoxGroupDefinition->GetCheckState(checkboxId, &ok) == CheckState::Checked;
    }
    return false;
}

OwnerPtr<IAction> CmdPickModuleEntry::ExecuteCommand(const CommandParameters& cmdParams)
{
    ModuleUIUtils::Get()->RemoveModuleUI();
    UiBuilder::CleanContextUI();
    if (PickFilterDlg* dlg = PickFilterDlg::Get())
    {
        dlg->ShowDock();
    }
    else
    {
        PickFilterDlg::Create();
    }

    if (GetRibbonGroup())
    {
        return nullptr;
    }

    std::wstring groupName = L"拾取模块示例";

    OwnerPtr<IRibbonGroup> opPickGroup = IRibbonGroup::Create(ID_GROUP_MODULE_PICK_CONTEXT, GBMP_TR(groupName));
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opPickGroup, L"opPickGroup为空",L"GDMP",L"2023-12-30");
    opPickGroup->SetGroupHandler(NEW_AS_OWNER_PTR(PickGroupHandler));

    OwnerPtr<IComboBoxDefinition> opComboBoxPickMethodDefinition =
        IComboBoxDefinition::Create(ID_COMBOBOX_PICK_METHOD, L"拾取API:");
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opComboBoxPickMethodDefinition, L"opComboBoxPickMethodDefinition为空",L"GDMP",L"2023-12-30");
    opComboBoxPickMethodDefinition->AddItem(L"Action拾取", PickMethod::PickNodeReferenceAction);
    opComboBoxPickMethodDefinition->AddItem(L"IPicker拾取", PickMethod::IPicker);
    opComboBoxPickMethodDefinition->AddItem(L"InteractivePicker", PickMethod::InteractivePicker);
    OwnerPtr<IComboBoxHandler> opComboBoxHandler = NEW_AS_OWNER_PTR(PickComboBoxHandler, ID_COMBOBOX_PICK_METHOD);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opComboBoxHandler, L"opComboBoxHandler为空",L"GDMP",L"2023-12-30");
    opComboBoxPickMethodDefinition->SetControlHandler(TransferOwnership(opComboBoxHandler));
    opPickGroup->AddComboBox(TransferOwnership(opComboBoxPickMethodDefinition));

    OwnerPtr<ICommandButtonDefinition> opPickWithActionDefinition =
        ICommandButtonDefinition::Create(ID_CMD_PICK_WITH_ACTION, GBMP_TR(L"Action拾取"),
            GBMP_TR(L"用IPickNodeReferenceAction拾取图元，可以在右侧过滤树和菜单中设置拾取API常用接口"),
            ID_CMD_PICK_WITH_ACTION, L":/images/Module/PickSnap/cursor_pick.png");
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opPickWithActionDefinition, L"opPickWithActionDefinition为空",L"GDMP",L"2023-12-30");
    opPickGroup->AddButton(TransferOwnership(opPickWithActionDefinition));

    OwnerPtr<ICommandButtonDefinition> opPickWithPickerDefinition =
        ICommandButtonDefinition::Create(ID_CMD_PICK_WITH_IPICKER, GBMP_TR(L"IPicker拾取"),
            GBMP_TR(L"用IPicker拾取图元，可以在右侧过滤树和菜单中设置拾取API常用接口"),
            ID_CMD_PICK_WITH_IPICKER, L":/images/Module/PickSnap/cursor_pick.png");
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opPickWithPickerDefinition, L"opPickWithPickerDefinition为空",L"GDMP",L"2023-12-30");
    opPickGroup->AddButton(TransferOwnership(opPickWithPickerDefinition));

    OwnerPtr<ICommandButtonDefinition> opPickWithInteractivePickerDefinition =
        ICommandButtonDefinition::Create(ID_CMD_PICK_WITH_INTERACTIVE_PICKER, GBMP_TR(L"InteractivePicker拾取"),
            GBMP_TR(L"用InteractivePicker拾取图元，可以在右侧过滤树和菜单中设置拾取API常用接口"),
            ID_CMD_PICK_WITH_INTERACTIVE_PICKER, L":/images/Module/PickSnap/cursor_pick.png");
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opPickWithInteractivePickerDefinition, L"opPickWithInteractivePickerDefinition为空",L"GDMP",L"2023-12-30");
    opPickGroup->AddButton(TransferOwnership(opPickWithInteractivePickerDefinition));

    OwnerPtr<ICheckBoxGroupDefinition> opCheckBoxGroupDefinition = ICheckBoxGroupDefinition::Create(ID_CHECKBOX_GROUP_PICK, L"拾取选项");
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opCheckBoxGroupDefinition, L"opCheckBoxGroupDefinition为空",L"GDMP",L"2023-12-30");
    opCheckBoxGroupDefinition->AddCheckBox(ID_CHECKBOX_SELECT_PICK, L"选择拾取图元", L"在拾取Action结束后将拾取的图元放入选择集", CheckState::Unchecked);
    opCheckBoxGroupDefinition->AddCheckBox(ID_CHECKBOX_OFFSET_RAY, L"偏移拾取直线", L"偏移拾取直线的起点，并且和视角有角度，显示射线", CheckState::Unchecked);
    opCheckBoxGroupDefinition->AddCheckBox(ID_CHECKBOX_IS_MULTIPLE, L"是否多选", 
        L"InteractivePicker::Select的isMultiSelect参数（命令开始前设置有效）", CheckState::Unchecked);
    opCheckBoxGroupDefinition->AddCheckBox(ID_CHECKBOX_VIEWPORT_CUTTED, L"可拾取视口裁切对象", L"设置接口IPicker::SetCanPickViewportCuttedGraphics", CheckState::Unchecked);
    opCheckBoxGroupDefinition->AddCheckBox(ID_CHECKBOX_CLEAR_SELECTION, L" 命令开始前删除选择集", L"CommandBase::ShouldClearSelectionBeforeExecution中做设置", CheckState::Unchecked);
    opCheckBoxGroupDefinition->AddCheckBox(ID_CHECKBOX_PICK_NULL, L" 没有选中时结束还是继续", 
        L"PickNodeReferenceOption::SetPickNullReturnPos,设置没有选中时结束命令还是继续拾取（每次拾取前设置有效）", CheckState::Unchecked);
    opCheckBoxGroupDefinition->AddCheckBox(ID_CHECKBOX_CUSTOM_ACTION, L" 使用自定义的SamplePickNodeReferenceAction", L"使用自定义的SamplePickNodeReferenceAction", CheckState::Unchecked);
    PickComboBoxHandler::UpdateCheckBoxGroup(opCheckBoxGroupDefinition.get(), PickMethod::PickNodeReferenceAction);
    opPickGroup->AddCheckBoxGroup(TransferOwnership(opCheckBoxGroupDefinition));

    OwnerPtr<ILineEditDefinition> opToleranceILineDefinition =
        ILineEditDefinition::Create(ID_LINE_PICK_TOLERANCE, L"拾取像素容差", LineEditInputType::InputInt);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opToleranceILineDefinition, L"opToleranceILineDefinition为空",L"GDMP",L"2023-12-30");
    opToleranceILineDefinition->SetControlHandler(NEW_AS_OWNER_PTR(PickLineEditHandler));
    opToleranceILineDefinition->SetText(L"10");
    opPickGroup->AddLineEdit(TransferOwnership(opToleranceILineDefinition));

    /*/ TODO：将来实现
    OwnerPtr<IComboBoxDefinition> opComboBoxPickStyleDefinition =
    IComboBoxDefinition::Create(ID_COMBOBOX_PICK_STYLE, L"拾取方式:");
    opComboBoxPickStyleDefinition->AddItem(L"点选");
    opComboBoxPickStyleDefinition->AddItem(L"框选");
    opComboBoxPickStyleDefinition->AddItem(L"多边形框选");
    opPickGroup->AddComboBox(TransferOwnership(opComboBoxPickStyleDefinition));
    OwnerPtr<IComboBoxHandler> opPickStyleComboBoxHandler = NEW_AS_OWNER_PTR(PickComboBoxHandler, ID_COMBOBOX_PICK_STYLE);
    opComboBoxPickStyleDefinition->SetControlHandler(TransferOwnership(opPickStyleComboBoxHandler));
    */

    OwnerPtr<ICommandButtonDefinition> opPickCreateModelDefinition =
        ICommandButtonDefinition::Create(ID_CMD_PICK_CREATE_MODEL, GBMP_TR(L"创建测试模型"),
            GBMP_TR(L"创建各种不同性质的模型，这些模型在拾取捕捉API接口设置不同选项的表现不同"),
            ID_CMD_PICK_CREATE_MODEL, L":/images/Module/Common/model.png");
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opPickCreateModelDefinition, L"opPickCreateModelDefinition为空",L"GDMP",L"2023-12-30");
    opPickGroup->AddButton(TransferOwnership(opPickCreateModelDefinition));

    OwnerPtr<ICommandButtonDefinition> opHelpDefinition =
        ICommandButtonDefinition::Create(ID_CMD_PICK_HELP, GBMP_TR(L"帮助"), GBMP_TR(L"打开GDMP在线帮助网站"),
            ID_CMD_PICK_HELP, L":/images/Module/Common/Help.png");
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opHelpDefinition, L"opHelpDefinition为空",L"GDMP",L"2023-12-30");
    opPickGroup->AddButton(TransferOwnership(opHelpDefinition));

    ModuleUIUtils::Get()->SetupModuleUI(TransferOwnership(opPickGroup), groupName);

    return nullptr;
}

#pragma endregion CmdPickModuleEntry

